home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmcd-1.4 / libdi.d / vu_tosh.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-10  |  9.6 KB  |  441 lines

  1. /*
  2.  *   libdi - CD Audio Player Device Interface Library
  3.  *
  4.  *   Copyright (C) 1995  Ti Kan
  5.  *   E-mail: ti@amb.org
  6.  *
  7.  *   This program is free software; you can redistribute it and/or modify
  8.  *   it under the terms of the GNU General Public License as published by
  9.  *   the Free Software Foundation; either version 2 of the License, or
  10.  *   (at your option) any later version.
  11.  *
  12.  *   This program is distributed in the hope that it will be useful,
  13.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *   GNU General Public License for more details.
  16.  *
  17.  *   You should have received a copy of the GNU General Public License
  18.  *   along with this program; if not, write to the Free Software
  19.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  *   The name "Toshiba" is a trademark of Toshiba Corporation, and is
  22.  *   used here for identification purposes only.  This software and its
  23.  *   author are not affiliated in any way with Toshiba.
  24.  *
  25.  */
  26. #ifndef LINT
  27. static char *_vu_tosh_c_ident_ = "@(#)vu_tosh.c    5.4 94/12/28";
  28. #endif
  29.  
  30. #include "common.d/appenv.h"
  31. #include "common.d/util.h"
  32. #include "libdi.d/libdi.h"
  33. #include "libdi.d/scsipt.h"
  34.  
  35. #ifdef VENDOR_TOSHIBA
  36.  
  37. extern appdata_t    app_data;
  38. extern vu_tbl_t        scsipt_vutbl[];
  39.  
  40. STATIC bool_t        tosh_audio_muted = FALSE;    /* Is audio muted? */
  41.  
  42.  
  43. /*
  44.  * tosh_playaudio
  45.  *    Play audio function: send vendor-unique play audio command
  46.  *    to the drive.
  47.  *
  48.  * Args:
  49.  *    addr_fmt - Flags indicating which address formats are passed in
  50.  *    If ADDR_BLK, then:
  51.  *        start_addr - The logical block starting address
  52.  *        end_addr - The logical block ending address
  53.  *    If ADD_MSF, then:
  54.  *        start_msf - Pointer to the starting MSF address structure
  55.  *        end_msf - Pointer to the ending MSF address structure
  56.  *    If ADDR_TRKIDX, then:
  57.  *        trk - The starting track number
  58.  *        idx - The starting index number
  59.  *    If ADDR_OPTEND, then the ending address, if specified, can be
  60.  *    ignored if possible.
  61.  *
  62.  * Return:
  63.  *    TRUE - success
  64.  *    FALSE - failure
  65.  */
  66. /*ARGSUSED*/
  67. bool_t
  68. tosh_playaudio(
  69.     byte_t        addr_fmt,
  70.     word32_t    start_addr,
  71.     word32_t    end_addr,
  72.     msf_t        *start_msf,
  73.     msf_t        *end_msf,
  74.     byte_t        trk,
  75.     byte_t        idx
  76. )
  77. {
  78.     bool_t        ret = FALSE;
  79.     word32_t    addr = 0;
  80.     taudio_arg_t    *p;
  81.  
  82.     p = (taudio_arg_t *) &addr;
  83.  
  84.     if (!ret && addr_fmt & ADDR_MSF) {
  85.         /* Position laser head at desired location
  86.          * and start play.
  87.          */
  88.         p->addr_min = (byte_t) ltobcd(start_msf->min);
  89.         p->addr_sec = (byte_t) ltobcd(start_msf->sec);
  90.         p->addr_frame = (byte_t) ltobcd(start_msf->frame);
  91.  
  92.         ret = pthru_send(
  93.             OP_VT_AUDSRCH,
  94.             addr, NULL, 0, 0, 0,
  95.             0x1, 0x1 << 6, READ_OP, TRUE
  96.         );
  97.  
  98.         if (ret && !(addr_fmt & ADDR_OPTEND)) {
  99.             /* Specify end location, muting, and start play */
  100.             p->addr_min = (byte_t) ltobcd(end_msf->min);
  101.             p->addr_sec = (byte_t) ltobcd(end_msf->sec);
  102.             p->addr_frame = (byte_t) ltobcd(end_msf->frame);
  103.  
  104.             ret = pthru_send(
  105.                 OP_VT_AUDPLAY,
  106.                 addr, NULL, 0, 0, 0,
  107.                 (byte_t) (tosh_audio_muted ? 0x0 : 0x3),
  108.                 0x1 << 6, READ_OP, TRUE
  109.             );
  110.         }
  111.     }
  112.  
  113.     if (!ret && addr_fmt & ADDR_BLK) {
  114.         /* Position laser head at desired location
  115.          * and start play.
  116.          */
  117.         p->addr_logical = start_addr;
  118.  
  119.         ret = pthru_send(
  120.             OP_VT_AUDSRCH,
  121.             addr, NULL, 0, 0, 0,
  122.             0x1, 0x0, READ_OP, TRUE
  123.         );
  124.  
  125.         if (ret && !(addr_fmt & ADDR_OPTEND)) {
  126.             /* Specify end location, muting, and start play */
  127.             p->addr_logical = end_addr;
  128.  
  129.             ret = pthru_send(
  130.                 OP_VT_AUDPLAY,
  131.                 addr, NULL, 0, 0, 0,
  132.                 (byte_t) (tosh_audio_muted ? 0x0 : 0x3),
  133.                 0x0, READ_OP, TRUE
  134.             );
  135.         }
  136.     }
  137.  
  138.     return (ret);
  139. }
  140.  
  141.  
  142. /*
  143.  * tosh_pause_resume
  144.  *    Pause/resume function: send vendor-unique commands to implement
  145.  *    the pause and resume capability.
  146.  *
  147.  * Args:
  148.  *    resume - TRUE: resume, FALSE: pause
  149.  *
  150.  * Return:
  151.  *    TRUE - success
  152.  *    FALSE - failure
  153.  */
  154. bool_t
  155. tosh_pause_resume(bool_t resume)
  156. {
  157.     if (resume) {
  158.         return (
  159.             pthru_send(
  160.                 OP_VT_AUDPLAY, 0, NULL, 0, 0, 0,
  161.                 (byte_t) (tosh_audio_muted ? 0x0 : 0x3),
  162.                 0x3 << 6, READ_OP, TRUE
  163.             )
  164.         );
  165.     }
  166.     else {
  167.         return (
  168.             pthru_send(
  169.                 OP_VT_STILL, 0, NULL, 0, 0, 0,
  170.                 0, 0, READ_OP, TRUE
  171.             )
  172.         );
  173.     }
  174. }
  175.  
  176.  
  177. /*
  178.  * tosh_get_playstatus
  179.  *    Send vendor-unique command to obtain current audio playback
  180.  *    status.
  181.  *
  182.  * Args:
  183.  *    s - Pointer to the curstat_t structure
  184.  *    audio_status - Address where a current status code (SCSI-2
  185.  *               style) is to be returned.
  186.  *
  187.  * Return:
  188.  *    TRUE - success
  189.  *    FALSE - failure
  190.  */
  191. bool_t
  192. tosh_get_playstatus(curstat_t *s, byte_t *audio_status)
  193. {
  194.     int        i,
  195.             trkno,
  196.             idxno;
  197.     byte_t        buf[sizeof(tsubq_data_t)];
  198.     tsubq_data_t    *d;
  199.  
  200.  
  201.     memset(buf, 0, sizeof(buf));
  202.  
  203.     if (!pthru_send(OP_VT_RDSUBQ, 0, buf, SZ_VT_RDSUBQ, 0, 0,
  204.                SZ_VT_RDSUBQ, 0, READ_OP, TRUE))
  205.         return FALSE;
  206.  
  207.     DBGDUMP("tosh: Read Subchannel data bytes", buf, SZ_VT_RDSUBQ);
  208.  
  209.     d = (tsubq_data_t *)(void *) buf;
  210.  
  211.     trkno = bcdtol((word32_t) d->trkno);
  212.     if (s->cur_trk != trkno) {
  213.         s->cur_trk = trkno;
  214.         dpy_track(s);
  215.     }
  216.  
  217.     idxno = bcdtol((word32_t) d->idxno);
  218.     if (s->cur_idx != idxno) {
  219.         s->cur_idx = idxno;
  220.         s->sav_iaddr = s->cur_tot_addr;
  221.         dpy_index(s);
  222.     }
  223.  
  224.     if ((i = curtrk_pos(s)) >= 0)
  225.         s->trkinfo[i].type = (d->trktype == 0) ? TYP_AUDIO : TYP_DATA;
  226.  
  227.     s->cur_tot_min = (byte_t) bcdtol(d->abs_min);
  228.     s->cur_tot_sec = (byte_t) bcdtol(d->abs_sec);
  229.     s->cur_tot_frame = (byte_t) bcdtol(d->abs_frame);
  230.     s->cur_trk_min = (byte_t) bcdtol(d->rel_min);
  231.     s->cur_trk_sec = (byte_t) bcdtol(d->rel_sec);
  232.     s->cur_trk_frame = (byte_t) bcdtol(d->rel_frame);
  233.     msftoblk(
  234.         s->cur_tot_min, s->cur_tot_sec, s->cur_tot_frame,
  235.         &s->cur_tot_addr, MSF_OFFSET(s)
  236.     );
  237.     msftoblk(
  238.         s->cur_trk_min, s->cur_trk_sec, s->cur_trk_frame,
  239.         &s->cur_trk_addr, 0
  240.     );
  241.  
  242.     /* Translate Toshiba audio status to SCSI-2 audio status */
  243.     switch (d->audio_status) {
  244.     case TAUD_PLAYING:
  245.         *audio_status = AUDIO_PLAYING;
  246.         break;
  247.  
  248.     case TAUD_SRCH_PAUSED:
  249.     case TAUD_PAUSED:
  250.         *audio_status = AUDIO_PAUSED;
  251.         break;
  252.  
  253.     case TAUD_OTHER:
  254.         *audio_status = AUDIO_COMPLETED;
  255.         break;
  256.     }
  257.  
  258.     return TRUE;
  259. }
  260.  
  261.  
  262. /*
  263.  * tosh_get_toc
  264.  *    Send vendor-unique command to obtain the disc table-of-contents
  265.  *
  266.  * Args:
  267.  *    s - Pointer to the curstat_t structure, which contains the TOC
  268.  *        table to be updated.
  269.  *
  270.  * Return:
  271.  *    TRUE - success
  272.  *    FALSE - failure
  273.  */
  274. bool_t
  275. tosh_get_toc(curstat_t *s)
  276. {
  277.     int        i,
  278.             j;
  279.     byte_t        buf[SZ_VT_RDINFO];
  280.     tinfo_00_t    *t0;
  281.     tinfo_01_t    *t1;
  282.     tinfo_02_t    *t2;
  283.  
  284.  
  285.     memset(buf, 0, sizeof(buf));
  286.  
  287.     /* Find number of tracks */
  288.     if (!pthru_send(OP_VT_RDINFO, 0, buf, SZ_VT_RDINFO,
  289.             0, 0, 0, 0, READ_OP, TRUE))
  290.         return FALSE;
  291.  
  292.     DBGDUMP("tosh: Read Disc Info data bytes", buf, SZ_VT_RDINFO);
  293.  
  294.     t0 = (tinfo_00_t *) buf;
  295.     s->first_trk = (byte_t) bcdtol(t0->first_trk);
  296.     s->last_trk = (byte_t) bcdtol(t0->last_trk);
  297.  
  298.     /* Get the starting position of each track */
  299.     for (i = 0, j = (int) s->first_trk; j <= (int) s->last_trk; i++, j++) {
  300.         memset(buf, 0, sizeof(buf));
  301.  
  302.         if (!pthru_send(OP_VT_RDINFO, ltobcd(j) << 24,
  303.                 buf, SZ_VT_RDINFO, 0, 0, 2,
  304.                 0, READ_OP, TRUE))
  305.             return FALSE;
  306.  
  307.         DBGDUMP("tosh: Read Disc Info data bytes", buf, SZ_VT_RDINFO);
  308.  
  309.         t2 = (tinfo_02_t *) buf;
  310.  
  311.         s->trkinfo[i].trkno = j;
  312.         s->trkinfo[i].min = (byte_t) bcdtol(t2->min);
  313.         s->trkinfo[i].sec = (byte_t) bcdtol(t2->sec);
  314.         s->trkinfo[i].frame = (byte_t) bcdtol(t2->frame);
  315.         msftoblk(
  316.             s->trkinfo[i].min,
  317.             s->trkinfo[i].sec,
  318.             s->trkinfo[i].frame,
  319.             &s->trkinfo[i].addr,
  320.             MSF_OFFSET(s)
  321.         );
  322.     }
  323.     s->tot_trks = (byte_t) i;
  324.  
  325.     memset(buf, 0, sizeof(buf));
  326.  
  327.     /* Get the lead out track position */
  328.     if (!pthru_send(OP_VT_RDINFO, 0,
  329.             buf, SZ_VT_RDINFO, 0, 0, 1,
  330.             0, READ_OP, TRUE))
  331.         return FALSE;
  332.  
  333.     DBGDUMP("tosh: Read Disc Info data bytes", buf, SZ_VT_RDINFO);
  334.  
  335.     t1 = (tinfo_01_t *) buf;
  336.  
  337.     s->trkinfo[i].trkno = LEAD_OUT_TRACK;
  338.     s->tot_min = s->trkinfo[i].min = (byte_t) bcdtol(t1->min);
  339.     s->tot_sec = s->trkinfo[i].sec = (byte_t) bcdtol(t1->sec);
  340.     s->tot_frame = s->trkinfo[i].frame = (byte_t) bcdtol(t1->frame);
  341.     msftoblk(
  342.         s->trkinfo[i].min,
  343.         s->trkinfo[i].sec,
  344.         s->trkinfo[i].frame,
  345.         &s->trkinfo[i].addr,
  346.         MSF_OFFSET(s)
  347.     );
  348.     s->tot_addr = s->trkinfo[i].addr;
  349.  
  350.     return TRUE;
  351. }
  352.  
  353.  
  354. /*
  355.  * tosh_mute
  356.  *    Send vendor-unique command to mute/unmute the audio
  357.  *
  358.  * Args:
  359.  *    mute - TRUE: mute audio, FALSE: unmute audio
  360.  *
  361.  * Return:
  362.  *    TRUE - success
  363.  *    FALSE - failure
  364.  */
  365. bool_t
  366. tosh_mute(bool_t mute)
  367. {
  368.     curstat_t    *s = curstat_addr();
  369.  
  370.     if (tosh_audio_muted != mute) {
  371.         switch (s->mode) {
  372.         case M_NODISC:
  373.         case M_STOP:
  374.         case M_PAUSE:
  375.             break;
  376.  
  377.         default:
  378.             if (!pthru_send(OP_VT_AUDPLAY, 0, NULL, 0, 0, 0,
  379.                     (byte_t) (mute ? 0x0 : 0x3),
  380.                     0x3 << 6, READ_OP, TRUE))
  381.                 return FALSE;
  382.             break;
  383.         }
  384.  
  385.         tosh_audio_muted = mute;
  386.     }
  387.  
  388.     return TRUE;
  389. }
  390.  
  391.  
  392. /*
  393.  * tosh_eject
  394.  *    Send vendor-unique command to eject the caddy
  395.  *
  396.  * Args:
  397.  *    Nothing.
  398.  *
  399.  * Return:
  400.  *    TRUE - success
  401.  *    FALSE - failure
  402.  */
  403. bool_t
  404. tosh_eject(void)
  405. {
  406.     return (pthru_send(OP_VT_EJECT, 0, NULL, 0, 0, 0, 1, 0, READ_OP, TRUE));
  407. }
  408.  
  409.  
  410. /*
  411.  * tosh_init
  412.  *    Initialize the vendor-unique support module
  413.  *
  414.  * Args:
  415.  *    Nothing.
  416.  *
  417.  * Return:
  418.  *    Nothing.
  419.  */
  420. void
  421. tosh_init(void)
  422. {
  423.     /* Register vendor_unique module entry points */
  424.     scsipt_vutbl[VENDOR_TOSHIBA].vendor = "Toshiba";
  425.     scsipt_vutbl[VENDOR_TOSHIBA].playaudio = tosh_playaudio;
  426.     scsipt_vutbl[VENDOR_TOSHIBA].pause_resume = tosh_pause_resume;
  427.     scsipt_vutbl[VENDOR_TOSHIBA].start_stop = NULL;
  428.     scsipt_vutbl[VENDOR_TOSHIBA].get_playstatus = tosh_get_playstatus;
  429.     scsipt_vutbl[VENDOR_TOSHIBA].volume = NULL;
  430.     scsipt_vutbl[VENDOR_TOSHIBA].route = NULL;
  431.     scsipt_vutbl[VENDOR_TOSHIBA].mute = tosh_mute;
  432.     scsipt_vutbl[VENDOR_TOSHIBA].get_toc = tosh_get_toc;
  433.     scsipt_vutbl[VENDOR_TOSHIBA].eject = tosh_eject;
  434.     scsipt_vutbl[VENDOR_TOSHIBA].start = NULL;
  435.     scsipt_vutbl[VENDOR_TOSHIBA].halt = NULL;
  436. }
  437.  
  438.  
  439. #endif    /* VENDOR_TOSHIBA */
  440.  
  441.